{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# AutoGen Tool Use Example "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Import the Needed Packages "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import json\n",
    "\n",
    "import requests\n",
    "from autogen_agentchat.agents import AssistantAgent\n",
    "from autogen_core.models import UserMessage\n",
    "from autogen_ext.models.azure import AzureAIChatCompletionClient\n",
    "from azure.core.credentials import AzureKeyCredential\n",
    "from autogen_core import CancellationToken\n",
    "from autogen_core.tools import FunctionTool\n",
    "from autogen_agentchat.messages import TextMessage\n",
    "from autogen_agentchat.ui import Console\n",
    "from typing import Any, Callable, Set, Dict, List, Optional"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating the Client \n",
    "\n",
    "In this sample, we will use [GitHub Models](https://aka.ms/ai-agents-beginners/github-models) for access to the LLM. \n",
    "\n",
    "The `model` is defined as `gpt-4o-mini`. Try changing the model to another model available on the GitHub Models marketplace to see the different results. \n",
    "\n",
    "As a quick test, we will just run a simple prompt - `What is the capital of France`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client = AzureAIChatCompletionClient(\n",
    "    model=\"gpt-4o-mini\",\n",
    "    endpoint=\"https://models.inference.ai.azure.com\",\n",
    "    # To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.\n",
    "    # Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens\n",
    "    credential=AzureKeyCredential(os.environ[\"GITHUB_TOKEN\"]),\n",
    "    model_info={\n",
    "        \"json_output\": True,\n",
    "        \"function_calling\": True,\n",
    "        \"vision\": True,\n",
    "        \"family\": \"unknown\",\n",
    "    },\n",
    ")\n",
    "\n",
    "result = await client.create([UserMessage(content=\"What is the capital of France?\", source=\"user\")])\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Defining the Functions \n",
    "\n",
    "In this example, we will give the agent access to a tool that is a function with a list of available vacation destinations and their availability. \n",
    "\n",
    "You can think that this would be a scenario where a travel agent might have an access to a travel database for example. \n",
    "\n",
    "As you go through this sample, feel free to try to define new functions and tools that the agent can call. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import Dict, List, Optional\n",
    "\n",
    "\n",
    "def vacation_destinations(city: str) -> tuple[str, str]:\n",
    "    \"\"\"\n",
    "    Checks if a specific vacation destination is available\n",
    "    \n",
    "    Args:\n",
    "        city (str): Name of the city to check\n",
    "        \n",
    "    Returns:\n",
    "        tuple: Contains city name and availability status ('Available' or 'Unavailable')\n",
    "    \"\"\"\n",
    "    destinations = {\n",
    "        \"Barcelona\": \"Available\",\n",
    "        \"Tokyo\": \"Unavailable\",\n",
    "        \"Cape Town\": \"Available\",\n",
    "        \"Vancouver\": \"Available\",\n",
    "        \"Dubai\": \"Unavailable\",\n",
    "    }\n",
    "\n",
    "    if city in destinations:\n",
    "        return city, destinations[city]\n",
    "    else:\n",
    "        return city, \"City not found\"\n",
    "\n",
    "# Example usage:\n",
    "# city, status = vacation_destinations(\"Barcelona\")\n",
    "# print(f\"How about visiting {city}? It's currently {status} there!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Defining the Function Tool \n",
    "To have the agent use the `vacation_destinations` as a `FunctionTool`, we need to define it as one. \n",
    "\n",
    "We will also provide a description of the to tool which is helpful for the agent to identify what that tool is used for in relation to the task the user has requested. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "get_vacations = FunctionTool(\n",
    "    vacation_destinations, description=\"Search for vacation destinations and if they are available or not.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Defining the agent \n",
    "\n",
    "Now we can create the agent in the below code. We define the `system_message` to give the agent instructions on how to help users find vacation destinations. \n",
    "\n",
    "We also set the `reflect_on_tool_use` parameter to true. This allows use the LLM to take the response of the tool call and send the response using natural language. \n",
    "\n",
    "You can set the the parameter to false to see the difference. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = AssistantAgent(\n",
    "    name=\"assistant\",\n",
    "    model_client=client,\n",
    "    tools=[get_vacations],\n",
    "    system_message=\"You are a travel agent that helps users find vacation destinations.\",\n",
    "    reflect_on_tool_use=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Running the Agent \n",
    "\n",
    "Now we can run the agent with the initial user message asking to take a trip to Tokyo. \n",
    "\n",
    "You can change this city desintation to see how the agent responds to the availablity of the city. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "async def assistant_run() -> None:\n",
    "    response = await agent.on_messages(\n",
    "        [TextMessage(content=\"I would like to take a trip to Tokyo\", source=\"user\")],\n",
    "        cancellation_token=CancellationToken(),\n",
    "    )\n",
    "    print(response.inner_messages)\n",
    "    print(response.chat_message)\n",
    "\n",
    "\n",
    "# Use asyncio.run(assistant_run()) when running in a script.\n",
    "await assistant_run()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
